\chapter{Construcción del prototipo} % (fold)
\label{cha:prototipo}

En este capítulo exponemos la implementación de un prototipo de celda de
almacenamiento que cumple con nuestra propuesta. Para ello, la infraestructura
disponible constó de cinco computadoras conectadas en red, cuyas
características básicas son:

\begin{itemize}
 \item Procesador Intel Pentium Dual-Core a 2.7 GHz.
 \item 2 GB the memoria RAM.
 \item Disco duro con capacidad 500 GB.
 \item Un switch \textit{Cisco Small Business} SF 1000-08.
\end{itemize}

\begin{figure}[ht]
 \centering
 \includegraphics[width=0.6\textwidth]{images/prototipo}
 \caption{Correspondencia entre la implementación del prototipo y la arquitectura
 propuesta}
 \label{fig:prototipo}
\end{figure}

\section{Funcionalidad del Sistema} % (fold)

\label{sec:funcionalidad}

Con el objetivo de probar el modelo arquitectónico propuesto, implementamos una
celda de almacenamiento, utilizando la infraestrucura mencionada anteriormente,
sobre las computadoras disponibles, instalamos cinco espacios virtuales de
almacenamiento, y un representante, el cual es el responsable de interactuar
con los usuarios y delegar las tareas de almacenamiento y recuperación de
archivos.

La idea de la celda de almacenamiento es obtener un dispositivo virtual, que
sea capaz de garantizar la integridad y confidencialidad de los datos
almacenados en él, es decir, es un espacio de almacenamiento autónomo y
confiable, esto es un aspecto de diseño considerado por~\cite{weil}. Para
efectos de este prototipo, la celda que implementamos tiene la capacidad de
otorgar, en un principio, dos diferentes ``niveles de servicio'' a sus
usuarios: almacenar sus datos replicados, o codificados utilizando el algoritmo
de dispersión de información~\cite{rabin}, ambas opciones ayudan a mejorar la
integridad y disponibilidad de la información. La replicación simple es una
estrategia más económica en términos de procesamiento, pero es más costosa en
cuanto al consumo de espacio de almacenamiento se refiere, por otro lado, la
codificación por medio del algoritmo de dispersión de información, aunque más
costosa en procesamiento, ofrece las ventajas de ser más económica en costo de
almacenamiento y abre la posibilidad de soportar la falla de hasta dos espacios
virtuales de almacenamiento, según la implentación actual del algoritmo.

En la figura~\ref{fig:prototipo} ilustramos la correspondencia entre la
arquitectura que proponemos y el prototipo que desarrollamos. En este diagrama
expresamos cuales de los módulos corresponden con los componentes de la
arquitectura propuesta.  

% section funcionalidad (end)

\section{Modelo de Comunicación} % (fold)
\label{sec:coms}

\begin{wrapfigure}{r}{0.5\textwidth}%[ht]
% \begin{figure}
 \centering
 \includegraphics[width=0.4\textwidth]{images/xmlrpc}
 \caption{Modelo XMLRPC~\cite{merrick}}
 \label{fig:xmlrpc}
% \end{figure}
\end{wrapfigure}

Como modelo de comunicación elegimos XMLRPC~\cite{merrick}, porque permite
conectar clientes y servidores, sin importar el lenguaje de programación en
que estén escritos; de cualquier manera, el diseño de la arquitectura no
impone restricciones sobre el modelo de comunicación que pueda elegirse en
otras implementaciones (Ver figura \ref{fig:xmlrpc}).

El proceso general de comunicación, se ilustra en la figura~\ref{fig:nodos}. 
Cuando un \textbf{Cliente} desea enviar un mensaje $x$ para realizar una
petición $i$, lo pasa como parámetro a su método correspondiente $f_i$, desde
donde se invoca un método privado especial, ilustrado en la figura como
$enviar()$, que recibe dos parámetros: uno de ellos es una clave $k_i$
correspondiente a la petición realizada y el otro es el mensaje $x$. Con estos
parámetros, el \textbf{Cliente} invoca el método remoto ilustrado como
$atender$, quien es el encargado de recibir el mensaje $x$, toma la clave
$k_i$, y con ella, el \textbf{Servidor} selecciona el servicio correspondiente
del \textbf{Manejador} para atender la petición del \textbf{Cliente}. Una vez
que la operación fue realizada, el valor de retorno del método $atender()$ es
devuelto al \textbf{Cliente}, para reportar el estado en que terminó la
invocación remota.

\begin{wrapfigure}{l}{0.5\textwidth}%[ht]
% \begin{figure}%[ht]
 \centering
 \includegraphics[width=0.47\textwidth]{images/clienteservidor}
 \caption{Esquema general de comunicación entre nodos}
 \label{fig:nodos}
% \end{figure}
\end{wrapfigure}

Por otro lado, el diseño que se muestra en la figura~\ref{fig:nodos}a permite
que si la funcionalidad para algún tipo de petición no está implementada, se
puede dirigir el procesamiento a un método ``por defecto'', de esta manera,
si se quiere agregar una nueva funcionalidad en el \textbf{Servidor}, basta con
implementar un método en el \textbf{Manejador}, y conectarlo con la ``casilla''
correspondiente del \textbf{Servidor}, tal como se muestra en la
figura~\ref{fig:nodos}b.

La estructura básica de los mensajes consiste en envíar tuplas de la forma
$(codigo,datos)$, donde $codigo$ es un número entero que sirve para identificar
el tipo de mensaje, en caso de una petición, indica de qué petición se trata, y
en caso de las respuestas del servidor, indica si la operación terminó
exitosamente o no; por otro lado, la entrada $datos$ consta de una estructura
de datos que contiene el mensaje en sí, que puede ser, por ejemplo los datos
necesarios para reconstruir un objeto.

Con estos conceptos, definimos clases ``abstractas'' tanto para el cliente, el
servidor y el manejador de peticiones que se conecta él. En el caso de los
clientes, la clase base es RawClient \index{RawClient}, a partir de ella
especializamos dos tipos de cliente, el primero, la clase Client, se encarga de
implementar el API que conecta el núcleo del sistema con su usuario final, ya
sea una persona u otra aplicación; el segundo, la clase NodeClient, se encarga
de habilitar a los EVA para intercambiar mensajes con sus vecinos y el nodo
representante, esta relación entre las clases cliente, se ilustra en la
figura~\ref{fig:clientes}.

% @TODO Revisar la redacción de esta parte.

\begin{figure}%[ht]
 \centering
 \includegraphics[width=0.97\textwidth]{images/clasesclientes}
 \caption{Definición de las clases cliente}
 \label{fig:clientes}
\end{figure}

En el caso de los servidores, se define una clase base llamada Node (definida
en el módulo server.sadnode) de la cual se especializan dos clases: Proxy y
Server. Las instancias de estas clases se encargan de las labores del
representante y los EVA respectivamente.

Tanto Proxy como Server, utilizan un manejador de peticiones para atender a sus
clientes, estos son instancias de las clases ProxyHandler y ServerHandler,
ambos, subclases de Handler, clase que también está definida en el módulo
server.sadnode. 

Finalmente, dotamos a los servidores de
la capacidad de atender varias peticiones al mismo tiempo, agregando un
``listener'' a la clase Node, llamado NodeListener (también definido en el
módulo server.sadnode), que es una clase vacía que simplemente hereda de las
clases ThreadingMixIn (definida en el módulo SocketServer) y SimpleXMLRPCServer
(definida en el módulo SimpleXMLRPCServer), todas estas relaciones entre las
clases mencionadas, se ilustran en la figura~\ref{fig:evas}.

\begin{figure}[ht]
 \centering
 \includegraphics[width=0.7\textwidth]{images/clasesservidores}
 \caption{Definición de las clases que componen los Espacios Virtuales de
 Almacenamiento (EVA)}
 \label{fig:evas}
\end{figure}

% section coms (end)

\section{Modelo de Datos} % (fold)
\label{sec:moddatos}

\begin{wrapfigure}{l}{0.45\textwidth}%[ht]
% \begin{figure}
 \centering
 \includegraphics[width=0.4\textwidth]{images/basedatos}
 \caption{Conexión con la Base de Datos}
 \label{fig:basedatos}
% \end{figure}
\end{wrapfigure}

En la arquitectura propuesta, el almacenamiento de los metadatos es delegado a
un sistema manejador de base de datos, en este prototipo, el manejador
elegido es PostgreSQL, el cual se conecta con la aplicación a través del módulo
psycopg2, tal como se ilustra en la figura \ref{fig:basedatos}, con el módulo
pgdata, del paquete db, en éste módulo se implementan las clases necesarias
para interactuar con un sistema manejador de base de datos dado. Si se quiere
extender la interoperabilidad del prototipo para que pueda utilizar un
manejador diferente, bastará con implementar una clase especial para cada uno,
respetando la interfaz definida por la clase PGDataBase definida en el módulo
db.pgdata; la idea es que toda interacción del sistema con la base de datos sea
a través de una clase de este tipo.

Por otro lado, se requieren tipos de datos que representen los objetos que se
van a procesar dentro de la celda, a saber, usuarios, archivos, fragmentos, y
bloques (tanto réplicas como fragmentos codificados), qué además sean
apropiados para enviarse empleando el modelo de comunicación descrito en la
sección \ref{sec:coms}. Para lograr esto, es necesario transformar los objetos
en una estructura que sea adecuada para formar parte de un mensaje, lo cual se
logra definiendo una clase base para todos estos tipos de datos, de la cual se
derivan todos los demás, tal como se ilustra en la figura \ref{fig:modelodatos}

\begin{figure}[ht]
 \centering
 \includegraphics[width=0.97\textwidth]{images/modelodatos}
 \caption{Modelo de Datos}
 \label{fig:modelodatos}
\end{figure}

% section moddatos (end)

\section{Metadatos} % (fold)
\label{sec:metadatos}

\begin{figure}%[ht]
 \centering
 \includegraphics[width=0.97\textwidth]{images/celdaer}
 \caption{Estructura de los metadatos utilizados por el sistema.}
 \label{fig:metadatos}
\end{figure}

Los metadatos son uno de los aspectos más importantes para el diseño del
prototipo; estos son utilizados para registrar los eventos que ocurren en el
sistema durante los procesos de almacenamiento y recupreración de información.
En los metadatos se registran los archivos que entran a la celda, qué EVA está
encargado de procesarlo para dividirlo en fragmentos, qué EVA se encargó de
crear los bloques de cada fragmento y en qué EVA se guardan los bloques
producidos. En resumen, los metadatos hacen posible que el sistema funcione
y pueda recuperarse de las fallas que sufra.

En el prototipo, los metadatos son almacenados en una base de datos relacional,
la cual tiene la misma estructura para cada EVA, sin embargo se encuentra
desacoplada de su implementación, como se ilustra en la figura
\ref{fig:basedatos}. El diseño de los metadatos se ilustra en la figura
\ref{fig:metadatos}, y lo explicamos a continuación:

\begin{description}

 \item[users] Es un registro de los usuarios del sistema, utilizado por el
  representante de la celda para autenticar y autorizar el acceso de un usuario
  al sistema.

 \item[groups] Es un catálogo de los grupos de usuario
  existentes.

 \item[membership] Es una interrelación de cardinalidad ``muchos a muchos'' que
  vincula las tablas users y groups, es decir que un usuario puede compartir
  sus contenidos con otros, creando grupos y asociando otros usuarios y
  sus archivos a los grupos que desee.

 \item[services] Es un catálogo de los servicios o niveles de servicio
  disponibles en la celda de almacenamiento, es decir, que además de poder
  almacenar archivos utilizando replicación simple y la codificación mediante
  ADI, se pueden agregar otros servicios que proporcionen una mayor variedad en
  los niveles de servicio que puede ofrecer la celda. 

 \item[usr2srv] Es una interrelación de cardinalidad ``muchos a muchos'' que
  vincula las tablas users y services, la cual permite brindar distintos
  niveles de servicio a los usuarios.

 \item[files] Es un registro empleado para tener un control sobre los archivos
  que se han almacenado en la celda, hacia qué EVA fueron delegados, a qué
  usuario pertenecen, y en qué versión se encuentran.

 \item[fragments] Cuando un EVA procesa un archivo y lo divide en fragmentos,
  utiliza esta  tabla para llevar un registro de en cuántos fragmentos fue
  dividido, a qué archivo pertenece cada fragmento, y a cuál de sus EVA vecinos
  delegó el procesamiento de cada uno de los fragmentos generados.

 \item[blocks] De manera similar, la tabla blocks es utilizada para llevar el
  registro de todos los boques generados, a qué fragmento pertenecen y de qué
  tipo de fragmento se trata (dependiendo del nivel de servicio con que se
  almacenó el archivo).

  \item[virtualspaces] Es un catálogo de los EVA disponibles dentro del
   sistema, el cual provee una posibilidad de almacenamiento al no limitar el
   número de EVA que pueden componer la celda de almacenamiento.

\end{description}

% section metadatos (end)

\section{Pruebas} % (fold)
\label{sec:pruebas}

\index{pruebas} \index{prototipo} \index{pruebas, ambiente de}
Dado que el prototipo aún se encuentra en una etapa temprana de su desarrollo,
las pruebas que se le realizaron se enfocaron a verificar su funcionamiento del
mismo. Durante el proceso de desarrollo el prototipo fue puesto en
funcionamiento sobre tres diferentes ambientes de pruebas; esto con la finalidad
de verificar el comportamiento que tienen los espacios virtuales de
almacenamiento cuando comparten el mismo nodo interno, o cuando interactuan con
EVAs que residen en diferentes sistemas operativos.

\subsection{Ambiente homogéneo} % (fold)
\label{sub:homogeneo}

En este ambiente se utilizaron cinco computadoras con las mismas caractarísticas
de hardware y el mismo software instalado. Se emplearon cinco computadoras de
escritorio para implementar la celda de almacenamiento con el siguiente
software:

\begin{itemize}
 \item Sistema Operativo Ubuntu Linux versión 10.10
 \item Intérprete de Python versión 2.6
 \item Manejador de base de datos PostgreSQL versión 8.4
\end{itemize}

Además el cliente de la celda de almacenamiento fue instalado en una computadora
portátil con sistema operativo Ubuntu Linux versión 10.04, intérprete de Python
versión 2.6 y manejador de base de datos PostgreSQL versión 8.4.

Utilizando estos recursos, cada uno de los cinco EVA que componen la celda se
alojó en cada una de las computadoras de escritorio, sin embargo una de las
computadoras hospedó también al proceso representante de la celda.

% subsubsection homogeneo (end)

\subsection{Ambiente heterogéneo} % (fold)
\label{sub:heterogeneo}

El segundo ambiente de pruebas, un poco más variado, constaba de seis
computadoras de escritorio, el siguiente software disponible:

\begin{itemize}
 \item Tres computadoras con sistema operativo Linux Fedora versión 15
 \item Dos computadoras con sistema operativo Slackware Linux versión 13.1
 \item Una computadora con sistema operativo Ubuntu Linux versión 10.04
 \item Todas las computadoras contaban con la versión 2.7 del intérprete de
       Python
 \item Las computadoras con sistema operativo Linux Fedora tienen instalado el
       manejador de base de datos PostgreSQL versión 9
 \item Tanto las dos máquinas con sistema operativo Slackware Linux como la
       computadora con sistema operativo Ubuntu Linux, tienen instalado el
	   manejador de base de datos PostgreSQL versión 8.4
\end{itemize}

% subsubsection heterogeneo (end)

\subsection{Ambiente reducido} % (fold)
\label{sub:reducido}

Este ambiente de pruebas consta de una sola computadora que hospeda a todos los
EVA, al representante de la celda y la aplicación cliente. Ciertamente este
escenario no es muy útil para poner en operación el sistema, pero fue el más
utilizado en la etapa de desarrollo del proyecto. Para este ambiente se
emplearó una computadora con sistema operativo OpenSuSE versión 11.4,
intérprete de Python versión 2.7 y manejador de base de datos PostgreSQL
versión 8.4.
% subsubsection reducido (end)

% subsection ambiente (end)

% section pruebas (end)

% chapter prototipo (end)
